package com.flyee.controller
{	
	import com.flyee.events.PanelStateChangeEvent;
	import com.flyee.service.pool.ObjectCollection;
	import com.flyee.utils.MyLog;
	import com.flyee.utils.Obsevable;
	import com.flyee.utils.Obsever;
	import com.flyee.viewer.BaseWindowViewer;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.GradientType;
	import flash.display.InterpolationMethod;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.Dictionary;
	import flash.utils.getDefinitionByName;
	
	import mx.containers.Panel;
	import mx.core.Application;
	import mx.core.DragSource;
	import mx.core.UIComponent;
	import mx.effects.Blur;
	import mx.effects.Fade;
	import mx.events.EffectEvent;
	import mx.managers.DragManager;

	/**
	 * 面板UI管理器，报括添加、删除、模糊、得到已有面板实例的方法
	 * @author zizhen
	 *
	 */
	public class UIController extends Obsevable implements Obsever
	{
		public static const TOP_LAYER:int = 1;
		public static const BOTTOM_LAYER:int = 0;
		public static const LAYER_INIT:int = 0;
		
		private var windowDictionary:Dictionary = null;
		private var removeList:Array = null;
		private var rootContainer:UIComponent = null;
		private var currentMask:UIComponent = null;

		public function UIController()
		{
			init();
		}

		private function init():void
		{
			windowDictionary = new Dictionary();
			removeList = new Array();
			rootOwner = ObjectCollection.uiContainer as UIComponent;
		}

		/**
		 * 设置根显示容器
		 * @param root
		 *
		 */
		public function set rootOwner(root:UIComponent):void
		{
			rootContainer = root;
		}

		public function get rootOwner():UIComponent{
			return rootContainer;
		}
		
		public function get contentSize():Point
		{
			var w:int = Application.application.width;
			var h:int = Application.application.height;
			var point:Point = new Point(w , h);
			return point;
		}
		
		public function execute(o : Obsevable, command : String=null, args : * = null):void{
			
		}
		
		public function redrawMask():void{
			if(currentMask){
				currentMask.graphics.clear();
				currentMask.graphics.beginFill(0xCCCCCC , 0.8);
				currentMask.graphics.drawRoundRect(0, 0, contentSize.x, contentSize.y,0);
				currentMask.graphics.endFill();
			}
		}

		public function drawMask(bounds:Sprite):UIComponent
		{
			var largeMask:UIComponent = new UIComponent();
			largeMask.graphics.beginFill(0xCCCCCC , 0.8);
			var topOffset:Number = 0;

			if (bounds is Panel)
			{
				var phh:Number = Panel(bounds).getStyle('headerHeight');
				topOffset += (phh) ? phh : 30;
			}
			largeMask.graphics.drawRoundRect(bounds.x - 10 , bounds.y + topOffset , bounds.width + 20 , bounds.height + 10 , 0);
			largeMask.graphics.endFill();
			bounds.parent.addChild(largeMask);
			currentMask = largeMask;
			return largeMask;
		}

		/**
		 *
		 *
		 */
		public function drawGradientCircle(uicomponet:UIComponent,screen:Number = 1280 ,height:Number = 1280, colorCenter:int = 0x66FFFF , colorBorder:int = 0x006699):void
		{
			var type:String = GradientType.RADIAL;
			var colors:Array = [colorCenter , colorBorder];
			var alphas:Array = [1 , 1];
			var ratios:Array = [0 , 255];
			var spreadMethod:String = SpreadMethod.PAD;
			var interp:String = InterpolationMethod.LINEAR_RGB;
			var focalPtRatio:Number = 0;
			var matrix:Matrix = new Matrix();
			var boxWidth:Number = screen;
			var boxHeight:Number = height;
			var boxRotation:Number = 0;
			// 90˚
			var tx:Number = 0;
			var ty:Number = 0;
			matrix.createGradientBox(boxWidth , boxHeight , boxRotation , tx , ty);
			uicomponet.graphics.clear();
			uicomponet.graphics.beginGradientFill(type , colors , alphas , ratios , matrix , spreadMethod , interp , focalPtRatio);
			uicomponet.graphics.drawRect(0 , 0 , screen , height);
		}
		
		/**
		 * 添加带底层遮罩的面板到桌面
		 * @param panelName
		 * @return
		 *
		 */
		public function addToDesktopWithMask(panelName:String , drag:Boolean = false , layer:int = TOP_LAYER , panelTag:String = null):UIComponent
		{
			/* 首先增加mask层 */
			if(!currentMask){
				addToDesktop(drawMask(rootContainer) , layer , false);
			}
			return addToDesktopByName(panelName , drag , layer , panelTag);
		}
		
		public function addPanelToDesktopWithMask(panel:UIComponent , layer:int , drag:Boolean = false):UIComponent{
			if(!currentMask){
				addToDesktop(drawMask(rootContainer) , layer , false);
			}
			return addToDesktop(panel , layer , drag);
		}

		public function addToDesktopByName(panelName:String , drag:Boolean = false , layer:int = TOP_LAYER , panelTag:String = null):UIComponent
		{
			if(panelName == null || panelName == "") return null;
			var displayObject:UIComponent = panelFactory(panelName , panelTag);
			addToDesktop(displayObject , layer , drag);
			return displayObject;
		}

		/**
		 * 向桌面添加一个面板
		 * @param panel
		 * @param name
		 * @return
		 *
		 */
		public function addToDesktop(panel:UIComponent , layer:int , drag:Boolean = false):UIComponent
		{
			if(panel == null) return null;
			var tag:String = panel.name;
			var show:Boolean = isDisplaying(tag);
			var container:UIComponent = panel;

			if (show)
			{
				container = windowDictionary[tag]as UIComponent;
				return container;
			}
			else
			{
				var effect:Fade = new Fade();
				effect.duration = 500;

				if (layer == TOP_LAYER)
				{
					var lay:int = rootContainer.numChildren;
					rootContainer.addChildAt(container , lay - LAYER_INIT);
				}
				else
				{
					rootContainer.addChildAt(container , 0);
				}
				MyLog.debug(tag + " index :" + rootContainer.getChildIndex(container));
				windowDictionary[tag] = container;
				effect.play([container]);

				if (drag)
				{

					if (container is BaseWindowViewer)
					{
						//AdvancedWindow(container).titleControlBar.addEventListener(MouseEvent.MOUSE_DOWN , mouseMoveEvent);
						BaseWindowViewer(container).canDragMove = true;
					}
					else
					{
						container.addEventListener(MouseEvent.MOUSE_DOWN , dragMoveEvent);
					}
				}
				return null;
			}
		}

		/**
		 * 判断该面板是否已经显示
		 * @param name
		 * @return
		 *
		 */
		public function isDisplaying(name:String):Boolean
		{

			for(var tag:String in windowDictionary)
			{

				if (name == tag)
				{
					return true;
				}
			}
			return false;
		}
		
		/**
		 * 从桌面删除带底层遮罩的面板
		 * @param panelName
		 * @return
		 *
		 */
		public function removedWithMask(panelName:String):Boolean
		{
			var container:UIComponent = windowDictionary[panelName]as UIComponent;
			if(currentMask && container){
				var first:int = rootContainer.getChildIndex(currentMask);
				var top:int = rootContainer.getChildIndex(container);
				if(isRemoveMask(first,top)){
					removedFromDesktop(currentMask);
					currentMask = null;
				}
			}
			return removedFromDesktopByName(panelName);
		}
		
		public function removedPanelWithMask(panel:UIComponent):Boolean{
			if(currentMask && panel){
				//var first:int = rootContainer.getChildIndex(currentMask);
				//var top:int = rootContainer.getChildIndex(panel);
				removedFromDesktop(currentMask);
				currentMask = null;
			}
			return removedFromDesktop(panel);
		}

		/**
		 * 从根容器根据name移除一个面板
		 * @param name
		 * @return
		 *
		 */
		public function removedFromDesktopByName(name:String):Boolean
		{
			var show:Boolean = isDisplaying(name);
			var container:UIComponent = null;

			if (show)
			{
				container = windowDictionary[name]as UIComponent;

				if (container && container.name == name)
				{
					var isRemoved:Boolean = removedFromDesktop(container);
					return isRemoved;
				}
			}
			return false;
		}

		public function removedFromDesktop(container:UIComponent):Boolean
		{

			if (rootContainer.contains(container))
			{
				var fadeEffect:Fade = new Fade();
				fadeEffect.duration = 500;
				fadeEffect.play([container] , true);
				fadeEffect.addEventListener(EffectEvent.EFFECT_END , effectEndEvent , false , 0 , true);
				removeList.push(container);
				return true;
			}
			return false;
		}

		/**
		 * 清除除了指定的窗口外的桌面上的所有窗口
		 *
		 */
		public function removeAllExceptByName(list:Array = null):void
		{
			var name:String = null;
			var tag:String = null;
			var except:Boolean = false;

			if (list && list.length > 0)
			{

				for(name in windowDictionary)
				{

					for(var i:int = 0 ; i < list.length ; i++)
					{
						tag = list[i];

						if (tag == name)
						{
							except = true;
							break;
						}
					}

					if (!except)
					{
						removedFromDesktopByName(name);
					}
					except = false;
				}
			}
			else
			{

				for(name in windowDictionary)
				{
					removedFromDesktopByName(name);
				}
			}
		/* while(hallContainer.numChildren > 0){
		   hallContainer.removeChildAt(0);
		 } */
		}

		/**
		 * 根据实例名称得到窗口实例引用
		 * @return
		 *
		 */
		public function getPanelByName(name:String):UIComponent
		{
			var show:Boolean = isDisplaying(name);
			var container:UIComponent = null;

			if (show)
			{
				container = windowDictionary[name]as UIComponent;
			}
			return container;
		}

		/**
		 * 把面板放到最顶层
		 * @param panel
		 *
		 */
		public function swapPanelToTop(panel:DisplayObjectContainer):void
		{
			var top:int = rootContainer.numChildren - LAYER_INIT - 1;

			if (top > -1)
			{
				rootContainer.setChildIndex(panel , top);
			}
		//var topPanel:UIComponent = rootContainer.getChildAt();
		}
		
		public function dispatchResizeEvent():void{
			for(var i:String in windowDictionary){
				var uic:UIComponent = windowDictionary[i];
				uic.dispatchEvent(new PanelStateChangeEvent(PanelStateChangeEvent.RESIZE));
			}
		}

		public function updateAllDisplayList():void
		{

			for(var i:*in windowDictionary)
			{
				var panel:UIComponent = windowDictionary[i];

				if (panel is BaseWindowViewer)
				{
					BaseWindowViewer(panel).validateDisplayList();
				}
			}
		}
		
		public function clearAll():void
		{
			for(var i:String in windowDictionary)
			{
				rootContainer.removeChild(windowDictionary[i]);
				delete windowDictionary[i];
			}
			rootContainer=null;
			removeList.splice(0);
			removeList=null;
			currentMask=null;
		}

		/**
		 * 模糊面板效果
		 * @param name
		 * @param blur
		 * @return
		 *
		 */
		public function blurPanelByName(name:String , blur:Boolean = true):Boolean
		{
			var show:Boolean = isDisplaying(name);
			var container:UIComponent = null;

			if (show)
			{
				container = windowDictionary[name]as UIComponent;

				if (container && container.name == name)
				{

					if (rootContainer.contains(container))
					{
						blurSprite(container , blur);
						return true;
					}
				}
			}
			return false;
		}
		
		private function isRemoveMask(first:int,top:int):Boolean{
			if(top - first == 1){
				return true;
			}
			return false;
		}

		private function blurSprite(sprite:Sprite , isBlur:Boolean):void
		{
			var effect:Blur = new Blur();

			if (!isBlur)
			{
				effect.blurXFrom = 0.0;
				effect.blurYFrom = 0.0;
				effect.blurXTo = 10.0;
				effect.blurYTo = 10.0;
			}
			else
			{
				effect.blurXFrom = 10.0;
				effect.blurYFrom = 10.0;
				effect.blurXTo = 0.0;
				effect.blurYTo = 0.0;
			}
			effect.play([sprite] , true);
		}

		private function panelFactory(className:String , tag:String = null):UIComponent
		{
			var target:UIComponent = getPanelByName(tag == null ? className : tag);

			if (!target)
			{
				try{
					var ClassReference:Class = getDefinitionByName(className)as Class
					target = new ClassReference();
	
					if (tag)
					{
						target.name = tag;
					}
					else
					{
						target.name = className;
					}
				}catch(error:ReferenceError){
					MyLog.error("factory error!!!! "+error.message);
				}
				
			}
			return target;
		}

		/**
		 *
		 * @param event
		 *
		 */
		private function effectEndEvent(event:EffectEvent):void
		{

			if (removeList && removeList.length > 0)
			{
				var container:UIComponent = removeList.shift();

				if (container.hasEventListener(MouseEvent.MOUSE_MOVE))
				{
					container.removeEventListener(MouseEvent.MOUSE_MOVE , mouseMoveEvent);
				}

				if (rootContainer.contains(container)){
					rootContainer.removeChild(container);
					container.dispatchEvent(new PanelStateChangeEvent(PanelStateChangeEvent.REMOVE));
				}	
				var tag:String = container.name;
				container = null;
				windowDictionary[tag] = null;
				delete windowDictionary[tag];
			}
		}

		/**
		 *
		 * @param event
		 *
		 */
		private function dragMoveEvent(event:MouseEvent):void
		{
			var dragInitiator:UIComponent = UIComponent(event.currentTarget);
			var ds:DragSource = new DragSource();
			ds.addData(new Point(dragInitiator.mouseX , dragInitiator.mouseY) , "point");
			DragManager.doDrag(dragInitiator , ds , event);
			swapPanelToTop(dragInitiator);
		}

		/**
		 *
		 * @param event
		 *
		 */
		private function mouseMoveEvent(event:MouseEvent):void
		{
			var self:UIComponent = UIComponent(event.currentTarget);
			var dragInitiator:UIComponent = self.parent as UIComponent;
			var ds:DragSource = new DragSource();
			ds.addData(new Point(self.mouseX , self.mouseY) , "point");
			DragManager.doDrag(dragInitiator , ds , event);
			swapPanelToTop(dragInitiator);
			event.updateAfterEvent();
		}
	}
}